package com.ra.landlord;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.googlecode.cswish.annotation.Rest;
import com.googlecode.cswish.exception.ApplicationException;
import com.googlecode.cswish.model.PageInfo;
import com.googlecode.cswish.oosearch.Condition;
import com.googlecode.cswish.struts.spring.GenericService;
import com.ra.landlord.constant.FeeRuleCalcMode;
import com.ra.landlord.constant.FeeRuleType;
import com.ra.system.Version;

/**
 * 费用规则服务
 * @author colin
 * @date 2014年9月14日
 */
@Service
public class FeeRuleCfgService {
	
	private final static Log logger = LogFactory.getLog(FeeRuleCfgDescService.class);
	
	@Resource
	private GenericService genericService;
	
	@Resource
	private LandlordUserService landlordUserService;
	
	@Resource
	private FeeRuleCfgDescService feeRuleCfgDescService;
	
	@PersistenceContext(unitName = "espirit")
	private EntityManager em;
	
	/**
	 * 新增固定费用规则
	 * @param model
	 * @return
	 */
	@Rest(type = "add")
	public FeeRuleCfg addFeeRule(FeeRuleCfg model){
		LandlordUser landlordUser = landlordUserService.getLoginUser();
		//默认规则有效0
		model.setType(0);
		model.setLandlordUser(landlordUser.getOwnerUser());
		
		FeeRuleCfgCalc feeRuleCfgCalc = model.getFeeRuleCfgCalc();
		feeRuleCfgCalc.setLandlordUser(landlordUser.getOwnerUser());
		//出租周期类型：0 - 月， 1 - 日 (暂未用)
		feeRuleCfgCalc.setRentCycleType(0);
		//阶梯计算，暂时没用
		feeRuleCfgCalc.setType(0);
		feeRuleCfgCalc.setPrice(feeRuleCfgCalc.getPrice().setScale(2, BigDecimal.ROUND_HALF_UP));
		
		FeeRuleCfgDesc feeRuleCfgDesc = genericService.load(model.getFeeRuleCfgDesc());
		model.setFeeRuleCfgDesc(feeRuleCfgDesc);
		
		return genericService.merge(model);
	}
	
	/**
	 * 新增费用项目，用于快速创建
	 * @param model
	 * @return
	 */
	@Rest(type = "add")
	public FeeRuleCfg addFeeRuleCfg(FeeRuleCfg model){
		LandlordUser landlordUser = landlordUserService.getLoginUser();
		model.setLandlordUser(landlordUser.getOwnerUser());
		model.getFeeRuleCfgCalc().setPrice(model.getFeeRuleCfgCalc().getPrice().setScale(2, BigDecimal.ROUND_HALF_UP));
		PageInfo<FeeRuleCfg> feeRuleCfgs = genericService.searchByModel(model, Condition.DEFAULT);
		if (feeRuleCfgs.getData().size() > 0) {
			throw new ApplicationException("该费用项已存在","10001");
		}
		
		//默认规则有效0
		model.setType(0);
		model.setStatus(Version.STATUS_VALID);
		
		FeeRuleCfgCalc feeRuleCfgCalc = model.getFeeRuleCfgCalc();
		feeRuleCfgCalc.setLandlordUser(landlordUser.getOwnerUser());
		//出租周期类型：0 - 月， 1 - 日 (暂未用)
		feeRuleCfgCalc.setRentCycleType(0);
		//阶梯计算，暂时没用
		feeRuleCfgCalc.setType(0);
		feeRuleCfgCalc.setPrice(feeRuleCfgCalc.getPrice().setScale(2, BigDecimal.ROUND_HALF_UP));

		FeeRuleCfgDesc feeRuleCfgDesc = model.getFeeRuleCfgDesc();
		feeRuleCfgDesc.setIsShare(false);
		feeRuleCfgDesc.setLandlordUser(landlordUser.getOwnerUser());
		
		return genericService.merge(model);
	}
	
	/**
	 * 查询固定费用的规则（包括仪表费用和固定费用）
	 * @param model
	 * @return
	 */
	@Rest(type = "search")
	public List<FeeRuleCfg> searchMeterFeeRule(FeeRuleCfg model){
		model.setStatus(Version.STATUS_VALID);
		PageInfo<FeeRuleCfg> pageInfo = genericService.search(model, 0, 1000, null, null, false, null, null, true, false);
		return pageInfo.getData();
	}
	
	/**
	 * 查询费用规则（包括仪表费用和固定费用）
	 * @param model
	 * @return
	 */
	@Rest(type = "search")
	public List<FeeRuleCfg> searchFeeRuleCfg(FeeRuleCfgDesc model){
		FeeRuleCfg feeRuleCfgModel = new FeeRuleCfg();
		feeRuleCfgModel.setFeeRuleCfgDesc(model);
		feeRuleCfgModel.setStatus(Version.STATUS_VALID);
		PageInfo<FeeRuleCfg> pageInfo = genericService.search(feeRuleCfgModel, 0, 1000, null, null, false, null, null, true, false);
		return pageInfo.getData();
	}
	
	/**
	 * 查询房东所有费用的规则
	 * 
	 * @return
	 */
	@Rest(type = "search")
	public List<FeeRuleCfg> searchFeeRule(Boolean isShare){
		FeeRuleCfg model = new FeeRuleCfg();
		model.setStatus(Version.STATUS_VALID);
		if (isShare != null) {
			FeeRuleCfgDesc feeRuleCfgDesc = new FeeRuleCfgDesc();
			feeRuleCfgDesc.setStatus(Version.STATUS_VALID);
			feeRuleCfgDesc.setIsShare(isShare);
			model.setFeeRuleCfgDesc(feeRuleCfgDesc);
			
			feeRuleCfgDesc.setIsShare(isShare);
		}
		PageInfo<FeeRuleCfg> pageInfo = genericService.search(model, 0, 1000, "feeRuleCfgDesc.type", null, false, null, null, true, false);
		return pageInfo.getData();
	}
	
	/**
	 * 新的删除费用规则接口，能够返回哪些费用规则已经被删除(当前APP在使用)
	 * @param model
	 * @return
	 */
	@Rest(type="delete")
	@Transactional
	public List<Integer> deleteFeeRuleCfg(List<Object> model) {
		// 检查费用规则是否有被用到
		List<Integer> delIds = new ArrayList<>();
		if (model != null) {
			for (int i = 0; i < model.size(); i++) {
				FeeRuleCfg feeRuleCfg = (FeeRuleCfg) model.get(i);
				feeRuleCfg = genericService.load(FeeRuleCfg.class,
						feeRuleCfg.getId());
				if (feeRuleCfg != null) {
					feeRuleCfg.setStatus(Version.STATUS_INVALID);
					genericService.update(feeRuleCfg);
					delIds.add(feeRuleCfg.getId());
				}
			}
		}
		return delIds;
	}
	
	
	@Rest(type="delete")
	@Transactional
	@Deprecated
	public boolean deleteFeeRule(List<Object> model) {
		//检查费用规则是否有被用到
		List<Object> delModel = new ArrayList<>();
		StringBuffer sb = new StringBuffer("FeeRuleCfg.id:");
		//校验，如果该记录已经被使用，则不能被删除，只要有一条被删除，就算删除成功
		if (model != null) 
		{
			
			for (int i = 0; i < model.size(); i++) 
			{
				FeeRuleCfg feeRuleCfg = (FeeRuleCfg)model.get(i);
				if (feeRuleCfg.getId() == null)
				{
					continue;
				}
				
				boolean isUsed = feeRuleCfgDescService.checkFeeRuleCfgUsedByRoom(feeRuleCfg);
				if (isUsed) 
				{
					sb.append(feeRuleCfg.getId()).append(",");
					logger.warn("该费用已被费用规则使用，不能删除！feeRuleCfg.id=" + feeRuleCfg.getId());
				}
				else
				{
					delModel.add(feeRuleCfg);
				}
			}
			if (delModel.size() == 0) 
			{
				String messageCode = "";
				if (sb.toString().length()>0) 
				{
					messageCode = sb.toString().substring(0, sb.toString().length()-1);
				}
				throw new ApplicationException("该费用规则已被使用，不能删除！", messageCode);
			}
		}
		
		return genericService.deleteList(delModel);
	}
	
	/**
	 * 自动添加费用
	 * @param building
	 * @param feeRuleCfgs
	 */
	public Boolean autoAddFeeRuleBatch(Building building, List<FeeRuleCfg> feeRuleCfgs){
		Building dbBuilding = genericService.load(building);
		LandlordUser landlordUser = landlordUserService.getLoginUser();
		FeeRule result = null;
		if (dbBuilding != null) {
			List<Room> rooms = dbBuilding.getRooms();
			if (rooms != null && rooms.size() > 0) {
				int num = 0 ;
				for (Room room : rooms) {
					List<FeeRule> feerules = room.getFeeRules();
					StringBuffer sb = new StringBuffer();
					if (feerules != null && feerules.size() > 0) {
						for (FeeRule feeRule : feerules) {
							sb.append(feeRule).append(",");
						}
					}
					String hasFeeRuleCfgIds = sb.toString();
					for (FeeRuleCfg feeRuleCfg : feeRuleCfgs) {
						if (hasFeeRuleCfgIds.indexOf(feeRuleCfg.getId()) == -1) {
							FeeRule newFeeRule = new FeeRule();
							newFeeRule.setFeeRuleCfg(feeRuleCfg);
							newFeeRule.setRoom(room);
							newFeeRule.setLandlordUser(landlordUser.getOwnerUser());
							newFeeRule.setStatus(Version.STATUS_VALID);
							newFeeRule.setVersion(1);
							result = genericService.add(newFeeRule);
							System.out.println("=========="+room.getName()+" 新增 收费项"+ num++ +"=======" + result.getId());
						}
					}
				}
			}
		}
		return true;
	}
	
	/**
	 * 为app流程优化而生
	 * 如果feeRuleCfg不存在（对应的描述，计费方式改变也算不存在）
	 * @param model 前台传递过来的feeRuleCfg
	 */
	@Transactional
	public FeeRuleCfg getOrGenerateFeeRuleCfg(FeeRuleCfg model) {
		FeeRuleCfg dbFeeRuleCfg = null;
		if (model.getFeeRuleCfgCalc().getValueLow() == null) {
			model.getFeeRuleCfgCalc().setValueLow(BigDecimal.valueOf(0));
		}
		Query query = em.createQuery("select a from " + FeeRuleCfg.class.getName() + 
				" a where a.status = 1 and a.feeRuleCfgDesc.name = ?1 and a.feeRuleCfgDesc.type = ?2 and a.feeRuleCfgDesc.calcMode = ?3 and (a.feeRuleCfgDesc.unit = ?4 or a.feeRuleCfgDesc.type = 1) "
				+ "and a.feeRuleCfgCalc.price - ?5 = 0 and a.feeRuleCfgCalc.valueLow - ?6 = 0 and a.landlordUser = ?7");
		query.setParameter(1, model.getFeeRuleCfgDesc().getName());
		query.setParameter(2, model.getFeeRuleCfgDesc().getType());
		query.setParameter(3, model.getFeeRuleCfgDesc().getCalcMode());
		query.setParameter(4, model.getFeeRuleCfgDesc().getUnit());
		query.setParameter(5, model.getFeeRuleCfgCalc().getPrice());
		query.setParameter(6, model.getFeeRuleCfgCalc().getValueLow());
		query.setParameter(7, landlordUserService.getLandlordOwnerUser());
		@SuppressWarnings("unchecked")
		List<FeeRuleCfg> resultList = query.getResultList();
		if (resultList != null && resultList.size() > 0) {
			dbFeeRuleCfg = resultList.get(0);
		} else {
			model.getFeeRuleCfgDesc().setIsShare(false);
			model.setLandlordUser(landlordUserService.getLandlordOwnerUser());
			model.getFeeRuleCfgCalc().setLandlordUser(landlordUserService.getLandlordOwnerUser());
			model.getFeeRuleCfgDesc().setLandlordUser(landlordUserService.getLandlordOwnerUser());
			model.getFeeRuleCfgCalc().setRentCycle(1);
			model.getFeeRuleCfgCalc().setRentCycleType(FeeRuleCfgCalc.RENT_CYCLE_TYPE_MONTH);
			
			//仅仅是数据库非空
			model.setType(0);
			model.getFeeRuleCfgCalc().setType(0);
			dbFeeRuleCfg = em.merge(model);
		}
		return dbFeeRuleCfg;
	}
	
	@Transactional
	public List<FeeRuleCfg> getOrGenerateFeeRuleCfgs(List<FeeRuleCfg> feeRuleCfgs) {
		ArrayList<FeeRuleCfg> dbFeeRuleCfgs = new ArrayList<FeeRuleCfg>(feeRuleCfgs.size());
		for (FeeRuleCfg feeRuleCfg : feeRuleCfgs) {
			FeeRuleCfg dbFeeRuleCfg = getOrGenerateFeeRuleCfg(feeRuleCfg);
			dbFeeRuleCfgs.add(dbFeeRuleCfg);
		}
		LandlordUser landlordUser = landlordUserService.getLandlordUser();
		landlordUser.getLatestFeeRuleCfgs().clear();
		landlordUser.getLatestFeeRuleCfgs().addAll(dbFeeRuleCfgs);
		em.merge(landlordUser);
		return dbFeeRuleCfgs;
	}
	
	public List<FeeRuleCfg> getLatestFeeRuleCfgs() {
		return landlordUserService.getLandlordUser().getLatestFeeRuleCfgs();
	}
}
